{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using the `solaris` CLI to make training masks\n",
    "\n",
    "Geospatial data labels are rarely in the form of pixel masks; however, such masks are essential for training neural networks for segmentation tasks. We've provided functions and a CLI to standardize training mask creation so that users can convert their geospatial-format vector labels into ML-compatible training masks. If you'd prefer the Python API implementation, [there's a tutorial here](api_masks_tutorial.ipynb).\n",
    "\n",
    "There are two ways to create these masks with the CLI: one file at a time, or in batch based on a reference file. Each is described below. We'll start with describing the simple single-file mask creation case, then describe how to complete batch processing. If you have any questions about what the different types of masks look like, [check out the Python API tutorial for mask creation](api_masks_tutorial.ipynb).\n",
    "\n",
    "## Single mask creation with the CLI\n",
    "\n",
    "Once you have [installed solaris](../../installation.html), you will have access to the `make_masks` command in your command line prompt. This command has a number of possible arguments to control mask creation, described below. If you need a refresher on these within your command line, you can always run `make_masks -h` for usage instructions.\n",
    "\n",
    "### `make_masks` arguments\n",
    "\n",
    "- __--source\\_file__, __-s__: \\[str\\] The full path to a vector file file to create a mask from.\n",
    "- __--reference\\_image__, __-r__, \\[str\\] The full path to a georegistered image in the same coordinate system (for conversion to pixels) or in the target coordinate system (for conversion to a geographic coordinate reference system)\n",
    "- __--output\\_path__, __-o__: \\[str\\] The full path to the output file for the generated mask image.\n",
    "- __--geometry\\_column__, __-g__: \\[str\\] (default: `'geometry'`) The column containing footprint polygons to transform.\n",
    "- __--transform__, __-t__: Use this flag if the geometries are in a georeferenced coordinate system and need to be converted to pixel coordinates.\n",
    "- __--value__, __-v__: \\[int\\] (default: `255`) The value to set for labeled pixels in the mask.\n",
    "- __--footprint__, __-f__: If this flag is set, the mask will include filled-in building footprints as a channel.\n",
    "- __--edge__, __-e__: If this flag is set, the mask will include the building edges as a channel.\n",
    "- __--edge\\_width__, __-ew__: \\[int\\] (default: `3`) The pixel thickness of the edges in the edge mask. Only has an effect if __--edge__ or __-e__ is used.\n",
    "- __--edge\\_type__, __-et__: \\[str\\] (default: `inner`) Type of edge: either `'inner'` or `'outer'`. Only has an effect if __--edge__ or __-e__ is used.\n",
    "- __--contact__, __-c__: If this flag is set, the mask  will include contact points between buildings as a channel.\n",
    "- __--contact\\_spacing__, __-cs__: \\[int\\] (default: `10`) Sets the maximum distance between two buildings, in pixel units unless __--metric_widths__ is provided, that will be identified as a contact. Only has an effect if __--contact__ or __-c__ is used.\n",
    "- __--metric\\_widths__, __-m__: Use this flag if widths should be in metric units instead of pixel units.\n",
    "- __--batch__, __-b__: Use this flag if you wish to operate on multiple files in batch. In this case, __--argument\\_csv__ must be provided. See the batch processing section below for more details.\n",
    "- __--argument\\_csv__, __-a__: \\[str\\] The reference file for variable values for batch processing. It must contain columns to pass the source_file and reference_image arguments, and can additionally contain columns providing other arguments if you wish to define them differently for items in the batch. Only has an effect if the __--batch__ or __-b__ arguments are used. These columns must have the same names as the corresponding arguments. See the next section for more details on batch processing.\n",
    "- __--workers__, __-w__: \\[int\\] (default: `1`) The number of parallel processing workers to use for batch processing. This should not exceed the number of CPU cores available. See the next section for more details on batch processing.\n",
    "\n",
    "### `make_masks` CLI usage examples\n",
    "\n",
    "Assume you have fies for a GeoTIFF, `image.tif`,  and georegistered building footprint labels, `building_labels.geojson`:\n",
    "\n",
    "_Creating building footprint labels:_\n",
    "\n",
    "```console\n",
    "$ make_masks --source_file building_labels.geojson --reference_image image.tif --footprint --transform\n",
    "```\n",
    "\n",
    "Let's change the burn value to 1 for the footprints instead of 255:\n",
    "\n",
    "```console\n",
    "$ make_masks --source_file building_labels.geojson --reference_image image.tif --footprint --transform --value 1\n",
    "```\n",
    "\n",
    "\n",
    "What if your building labels are already in pixel coordinates in a CSV named `building_labels.csv`, and the geometries are in a column named `WKT_Pix`?\n",
    "\n",
    "```console\n",
    "$ make_masks --source_file building_labels.csv --reference_image image.tif --footprint --geometry_column WKT_Pix\n",
    "```\n",
    "\n",
    "What if you have the same CSV file as above, but instead of making just building footprints, you want outer borders of width 10 and also contact points for anything within 10 meters?\n",
    "\n",
    "```console\n",
    "$ make_masks --source_file building_labels.csv --reference_image image.tif --geometry_column WKT_Pix --footprint --edge --edge-type outer --edge-width 10 --contact --contact_spacing 10 --metric_widths \n",
    "```\n",
    "\n",
    "## Batch mask creation using the `solaris` CLI\n",
    "\n",
    "There's one additional requirement for batch mask creation: a CSV specifying the location of the label files, the reference images, and optionally any other arguments that you wish to modify on a mask-by-mask basis.\n",
    "\n",
    "### Creating the argument CSV\n",
    "\n",
    "The reference CSV has three required columns, which must be named __exactly__ as below:\n",
    "\n",
    "- __source_file__: the paths to vector-formatted label files that you wish to transform to masks.\n",
    "- __reference_image__: The paths to images that correspond to the same geographies as the vector labels that you're using.\n",
    "- __output_path__: The paths to save the output masks to.\n",
    "The values in these two columns must be matching geographies across the row, or you'll get empty masks! For both cases, we recommend using the absolute path to the files in each column rather than a relative path for consistency and clarity.\n",
    "\n",
    "If you wish to use different values for the other arguments to `make_masks` (e.g., if you wish to have different burn values for different masks), you can provide those values in the CSV as well. Just create a column with the same name as the argument that you're replacing, and make sure to provide a value for every row.\n",
    "\n",
    "### `make_masks` CLI batch processing examples\n",
    "\n",
    "Assume you have a CSV `mask_reference.csv` that specifies the path to your .geojson labels, matching reference images, and where you want those files saved, as described in the last section.\n",
    "\n",
    "Let's create footprint masks:\n",
    "\n",
    "```console\n",
    "$ make_masks --batch --argument_csv mask_reference.csv --footprint\n",
    "```\n",
    "\n",
    "What if you have a _lot_ of masks to make and you want to parallelize over four CPUs? (Make sure you have access to four CPU cores first!)\n",
    "\n",
    "```console\n",
    "$ make_masks --batch --argument_csv mask_reference.csv --footprint --workers 4\n",
    "```"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "solaris",
   "language": "python",
   "name": "solaris"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
